﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class SpawnManager : MonoSingleton<SpawnManager>
{
    //生成平台位置偏移量
    public float nextXPos = 0.554f;
    public float nextYPos = 0.645f;

    //一般平台
    private Vector3 startSpawnPos = new Vector3(-0.554f, -3.045f, 0);    
    private Vector3 nextSpawnPos;// 下一个生成平台位置  
    private int spawnPlatformCount;// 生成平台数量
    private bool isLeftSpawn;// 左边或右边生成

    //障碍物
    private bool isLeftSpawnObstacle;// 左边或右边生成障碍物
    private bool isObstacleSpawnOnce;// 每次换边只允许生成一个障碍物

    //钉子平台（与障碍物唯一不同在于钉子生成后，要附加生成一般平台）
    private bool isLeftSpawnSpike;// 左边或右边生成钉子
    private Vector3 spikeSpawnPos;// 钉子平台生成位置
    private Vector3 nextAfterSpikePos;// 钉子之后的一般平台位置
    private bool isSpikeSpawnOnce;// 每次换边只允许生成一个钉子平台
    private int afterSpikePlatform;// 钉子之后接着的一般平台数量

    private int randomExceptCommon;// 随机障碍物或者钉子

    //随机在一般平台上生成钻石Diamond
    private bool isStartSpawnDiamond;// 前五个平台不能生成钻石
    private float diamondPosYOffest;// 与一般平台的y轴偏移量

 
    /// <summary>
    /// 初始化Spawn各种属性
    /// </summary>
    public void InitSpawnProperty()
    {
        spawnPlatformCount = 0;
        isLeftSpawn = false;
        isLeftSpawnObstacle = false;
        isObstacleSpawnOnce = false;
        isLeftSpawnSpike = false;
        isSpikeSpawnOnce = false;
        isStartSpawnDiamond = false;
        diamondPosYOffest = 0.5f;
        //随机游戏主题
        DataManager.Instance.mGameData.gameTheme = Random.Range(0, ResManager.Instance.gameTheme.Length);
        print("游戏主题 = " + DataManager.Instance.mGameData.gameTheme);
        nextSpawnPos = startSpawnPos;
        for (int i = 0; i < 5; i++)
        {
            spawnPlatformCount = 5;
            DecidePath();
        }
        afterSpikePlatform = 0;
        isStartSpawnDiamond = true;
    }



    #region 生成一般平台（附加随机生成钻石）
    /// <summary>
    /// 确定路径
    /// </summary>
    public void DecidePath()
    {
        if (spawnPlatformCount > 0)
        {
            spawnPlatformCount--;
            SpawnDirection();               
        }
        else
        {           
            isLeftSpawn = !isLeftSpawn;
            spawnPlatformCount = Random.Range(1, 5);
            randomExceptCommon = Random.Range(0, 2);
            SpawnDirection();
        }
    }
    /// <summary>
    /// 生成方向
    /// </summary>
    private void SpawnDirection()
    {
        // 向左生成
        if (isLeftSpawn)
        {
            nextSpawnPos = new Vector3(nextSpawnPos.x - nextXPos, nextSpawnPos.y + nextYPos, nextSpawnPos.z);
        }
        // 向右生成
        else
        {
            nextSpawnPos = new Vector3(nextSpawnPos.x + nextXPos, nextSpawnPos.y + nextYPos, nextSpawnPos.z);
        }
        SpawnCommonPlatform();
    }
    /// <summary>
    /// 生成一般平台
    /// </summary>
    private void SpawnCommonPlatform()
    {
        GameObject go = ObjectPool.Instance.GetObj("CommonPlatform");      
        go.transform.position = nextSpawnPos;
        GetTheme(go);
        SpawnDiamond(5,nextSpawnPos + new Vector3(0, diamondPosYOffest, 0));
    }
    /// <summary>
    /// 随机生成钻石（random = 1时一定生成钻石）
    /// </summary>
    private void SpawnDiamond(int random, Vector3 pos)
    {
        if (isStartSpawnDiamond)
        {
            if (random - 1 == Random.Range(0, random))
            {
                GameObject go = ObjectPool.Instance.GetObj("Diamond");
                go.transform.position = pos;
            }
        }        
    }
    #endregion


    #region 障碍物生成
    /// <summary>
    /// 确定障碍物路径
    /// </summary>
    public void DecideObstaclePath()
    {
        if (spawnPlatformCount > 0)
        {
            if (!isObstacleSpawnOnce)
            {
                //换边后位置随机，几率自己定
                if (Random.Range(0, 5) < 1)
                {
                    isObstacleSpawnOnce = true;
                    isLeftSpawnObstacle = !isLeftSpawn;
                    SpawnObstacleDirection();
                }  
            }                      
        }
        else
        {
            if (!isObstacleSpawnOnce)
            {                
                isObstacleSpawnOnce = true;
                //如果前几个没生成障碍物，最后一个障碍物与一般平台同向
                isLeftSpawnObstacle = isLeftSpawn;
                SpawnObstacleDirection();
            }
            //每次换边前最后要将isObstacleSpawnOnce = false；为了下一次随机生成障碍物
            isObstacleSpawnOnce = false;
        }
    }
    /// <summary>
    /// 障碍物平台生成方向与当前一般平台方向相反
    /// </summary>
    private void SpawnObstacleDirection()
    {
        if (!isLeftSpawnObstacle)
        {                 
            SpawnObstaclePlatform().transform.position = new Vector3(nextSpawnPos.x + nextXPos, nextSpawnPos.y + nextYPos, nextSpawnPos.z);
        }
        else
        {           
            SpawnObstaclePlatform().transform.position = new Vector3(nextSpawnPos.x - nextXPos, nextSpawnPos.y + nextYPos, nextSpawnPos.z);
        }

    }
    /// <summary>
    /// 生成障碍物平台
    /// </summary>
    private GameObject SpawnObstaclePlatform()
    {
        GameObject go = ObjectPool.Instance.GetObj("ObstaclePlatform");      
        switch (DataManager.Instance.mGameData.gameTheme)
        {
            case 0:
                go.GetComponent<SpriteRenderer>().sprite = ResManager.Instance.springObstacle[Random.Range(0,ResManager.Instance.springObstacle.Length)];
                break;
            case 1:
                go.GetComponent<SpriteRenderer>().sprite = ResManager.Instance.winterObstacle[Random.Range(0, ResManager.Instance.winterObstacle.Length)];
                break;
            default:
                break;
        }
        return go;
    }
    #endregion


    #region 钉子及后续平台生成
    /// <summary>  
    /// 钉子同向生成 afterSpikeCount 个一般平台    
    /// </summary>
    /// <param name="afterSpikeCount"></param>
    public void SpawnPlatformAfterSpike()
    {
        GameObject go = ObjectPool.Instance.GetObj("CommonPlatform");   
        GetTheme(go);
        if (!isLeftSpawnSpike)
        {
            nextAfterSpikePos = new Vector3(nextAfterSpikePos.x + nextXPos, nextAfterSpikePos.y + nextYPos, nextAfterSpikePos.z);
            go.transform.position = nextAfterSpikePos;
        }
        else
        {
            nextAfterSpikePos = new Vector3(nextAfterSpikePos.x - nextXPos, nextAfterSpikePos.y + nextYPos, nextAfterSpikePos.z);
            go.transform.position = nextAfterSpikePos;
        }
    }
    /// <summary>
    /// 确定钉子平台路径
    /// </summary>
    public bool DecideSpikePath()
    {
        if (spawnPlatformCount > 0)
        {
            if (!isSpikeSpawnOnce)
            {
                //换边后位置随机，几率自己定
                if (Random.Range(0, 5) < 1)
                {
                    isSpikeSpawnOnce = true;
                    isLeftSpawnSpike = !isLeftSpawn;
                    SpawnSpikeDirection();
                    //（若不是在换边前最后一个位置）生成钉子平台后，原道路平台多生成2个
                    spawnPlatformCount += 2;    
                    return true;
                }
            }
        }
        else
        {
            if (!isSpikeSpawnOnce)
            {
                isSpikeSpawnOnce = true;
                //如果前几个没生成钉子，最后一个钉子与一般平台同向
                isLeftSpawnSpike = isLeftSpawn;
                SpawnSpikeDirection();
                return true;
            }
            //每次换边前最后要将isSpikeSpawnOnce = false；为了下一次随机生成钉子
            isSpikeSpawnOnce = false;
        }
        return false;
    }
    /// <summary>
    /// 钉子平台生成方向与当前一般平台方向相反
    /// </summary>
    private void SpawnSpikeDirection()
    {
        if (!isLeftSpawnSpike)
        {
            GameObject go = SpawnSpikePlatform();
            go.transform.position = new Vector3(nextSpawnPos.x + nextXPos, nextSpawnPos.y + nextYPos, nextSpawnPos.z);
            spikeSpawnPos = go.transform.position;
            nextAfterSpikePos = spikeSpawnPos;
        }
        else
        {
            GameObject go = SpawnSpikePlatform();
            go.transform.position = new Vector3(nextSpawnPos.x - nextXPos, nextSpawnPos.y + nextYPos, nextSpawnPos.z);
            spikeSpawnPos = go.transform.position;
            nextAfterSpikePos = spikeSpawnPos;
        }
    }
    /// <summary>
    /// 生成钉子平台
    /// </summary>
    /// <returns></returns>
    private GameObject SpawnSpikePlatform()
    {       
        GameObject go = ObjectPool.Instance.GetObj("SpikePlatform");  
        GetTheme(go);
        return go;
    }
    #endregion
        
    /// <summary>
    /// 得到已经确定主题的一般平台图片
    /// </summary>
    /// <param name="platform"></param>
    private void GetTheme(GameObject platform)
    {
        switch (DataManager.Instance.mGameData.gameTheme)
        {
            case 0:
                platform.GetComponent<SpriteRenderer>().sprite = ResManager.Instance.gameTheme[0];
                break;
            case 1:
                platform.GetComponent<SpriteRenderer>().sprite = ResManager.Instance.gameTheme[1];
                break;
            default:
                break;
        }
    }

    /// <summary>
    /// 随机障碍物与钉子平台（可扩展添加更多随机平台）
    /// </summary>
    public void RandomExceptCommonPlatform()
    {
        //如果钉子接着的平台需要生成则必须生成，无论接下来随机的是障碍物还是钉子
        if (afterSpikePlatform > 0)
        {
            afterSpikePlatform--;
            SpawnPlatformAfterSpike();
        }


        if (randomExceptCommon < 1)
        {
            DecideObstaclePath();            
        }
        //随机到钉子后不能直接一起生成后接平台，所以放在（afterSpikePlatform > 0）的下面
        else if (DecideSpikePath())
        {
            afterSpikePlatform = 4;
        }
    }

    #region 生成皮肤
    /// <summary>
    /// 生成玩家皮肤（皮肤数量更改也不影响生成）
    /// </summary>
    public void SpawnPlayerSkin(Transform parent)
    {
        for (int i = 0; i < ResManager.Instance.playerSkin.Length; i++)
        {
            GameObject go = Instantiate(ResManager.Instance.playerSkinPerfab, parent);
            go.GetComponentInChildren<UnityEngine.UI.Image>().sprite = ResManager.Instance.playerSkin[i];
            go.GetComponentInChildren<UnityEngine.UI.Image>().color = Color.gray;
            //注意有父节点，要更改local值
            go.transform.localPosition = new Vector3((i + 1) * 160 + 80, 0, 0);
            go.transform.localEulerAngles = Vector3.zero;
            go.transform.localScale = Vector3.one;
        }
        
    }
    #endregion


    #region 生成特效
    /// <summary>
    /// 游戏角色死亡特效
    /// </summary>
    public void SpawnPlayerDieEffect(Vector3 pos)
    {
        GameObject go = ObjectPool.Instance.GetObj("PlayerDieEffect");
        go.transform.position = pos;
    }
    #endregion
}